//
// Created by JZYFC on 2021/12/15.
//

#include "AddWnd.h"
#include "FontUtil.h"
#include "../inout/ddlinout.h"

#define ADD_WIDTH 540

#define ADD_HEIGHT 400

/*
 *  此窗口用于添加与修改数据
 */

day_data data;
bool dataUsable = false;
bool isModify = false;
list_head currentHead;

// TODO: tab切换
//WNDPROC prevEditProc;
//int currentPosition = 11;

//LRESULT CALLBACK EditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
//    switch (msg){
//        case WM_CHAR:
//        case WM_KEYDOWN: {
//            if (wParam == VK_TAB) {
//                HWND hParent = GetParent(hWnd);
//                SendMessage(hParent, msg, wParam, lParam);
//            }
//            return 0;
//        }
//        default:
//            CallWindowProc(prevEditProc, hWnd, msg, wParam, lParam);
//    }
//}

LRESULT CALLBACK AddProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

    HDC hdc;
    static PAINTSTRUCT ps;
    static TEXTMETRIC text_metric;

    static HFONT font;

    static RECT number = {
            94, 32, ADD_WIDTH - 418, ADD_HEIGHT - 349
    };
    static RECT numberEditBox = {
            154, 24, ADD_WIDTH - 306, ADD_HEIGHT - 344
    };
    static RECT startTime = {
            64, 80, ADD_WIDTH - 420 + 4, ADD_HEIGHT - 301
    };
    static RECT endTime = {
            160, 80, ADD_WIDTH - 316 + 4, ADD_HEIGHT - 301
    };
    static RECT firstVWord = {
            8, 120, ADD_WIDTH - 510, ADD_HEIGHT - 261
    };
    static RECT firstEditBox = {
            56, 112, 412, 256
    };
    static HWND editBoxes[12];
    int editBoxWidth = 72;
    int editBoxHeight = 32;
    static RECT content = {
            256, 45, ADD_WIDTH - 228 + 4, ADD_HEIGHT - 336
    };
    static RECT contentEditBox = {
            256, 72, ADD_WIDTH - 28, ADD_HEIGHT - 64
    };
    int VGap = 29;
    int x = 0;
    int y = 0;
    switch (msg) {
        case WM_CREATE:
            // Confirm btn
            HWND hConfirmBtn = CreateWindowEx(
                    WS_EX_LEFT,
                    L"Button",
                    L"确定",
                    WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                    312,
                    352,
                    144,
                    40,
                    hWnd,
                    (HMENU) 0xf0,
                    (HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
                    NULL
            );
            // CancelBtn
            HWND hCancelBtn = CreateWindowEx(
                    WS_EX_LEFT,
                    L"Button",
                    L"取消",
                    WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                    72,
                    352,
                    144,
                    40,
                    hWnd,
                    (HMENU) 0xf1,
                    (HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
                    NULL
            );

            font = (HFONT) GetStockObject(DEFAULT_GUI_FONT);

            hdc = GetDC(hWnd);

            SelectObject(hdc, font);

            GetTextMetrics(hdc, &text_metric);
            x = firstEditBox.left;
            y = firstEditBox.top;
            for (int i = 0; i < 2; i++) {
                for (int j = 0; j < 5; ++j) {
                    editBoxes[i * 5 + j] = CreateWindowEx(
                            0, L"EDIT",
                            NULL,
                            WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP | ES_LEFT | ES_NUMBER,
                            x + 1,
                            y + 1,
                            editBoxWidth - 2,
                            editBoxHeight - 2,
                            hWnd,
                            (HMENU) 0xe0,
                            (HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
                            NULL
                    );
                    y += editBoxHeight + 16;
                }
                y = firstEditBox.top;
                x += editBoxWidth + 32;
            }
            editBoxes[10] = CreateWindowEx(
                    0, L"EDIT",
                    NULL,
                    WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER | WS_TABSTOP | ES_LEFT | ES_MULTILINE |
                    ES_AUTOVSCROLL | ES_WANTRETURN,
                    contentEditBox.left + 1,
                    contentEditBox.top + 1,
                    contentEditBox.right - contentEditBox.left - 2,
                    contentEditBox.bottom - contentEditBox.top - 2,
                    hWnd,
                    (HMENU) 0xe0,
                    (HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
                    NULL
            );
            editBoxes[11] = CreateWindowEx(
                    0, L"EDIT",
                    NULL,
                    WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP | ES_LEFT | ES_NUMBER,
                    154 + 1,
                    24 + 1,
                    80 - 2,
                    32 - 2,
                    hWnd,
                    (HMENU) 0xe0,
                    (HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
                    NULL
            );

// TODO: tab切换
//            prevEditProc = (WNDPROC) GetClassLongPtr(editBoxes[0], GCLP_WNDPROC);
//            for (int i = 0; i < 12; ++i) {
//                SetClassLongPtr(editBoxes[i], GCLP_WNDPROC, EditProc);
//            }

            ReleaseDC(hWnd, hdc);

            EnumChildWindows(hWnd, EnumChildWndSetFont, (LPARAM) font);

            EnableWindow(editBoxes[11], true);
            if (isModify) {
                WCHAR buf[5];
                int *ptr = &(data.start_date.year);
                for (int i = 0; i < 10; ++i) {
                    swprintf(buf, 5, L"%d", *ptr);
                    SetWindowText(editBoxes[i], buf);
                    ptr += 1;
                }
                SetWindowText(editBoxes[10], data.todo);
                swprintf(buf, 5, L"%d", data.number);
                SetWindowText(editBoxes[11], buf);
                EnableWindow(editBoxes[11], false);
            }
            break;
        case WM_PAINT:
            // 文本
            VGap = 29 + text_metric.tmHeight;
            hdc = BeginPaint(hWnd, &ps);

            SelectObject(hdc, font);

            DrawText(hdc, L"开始时间 ", -1, &startTime, DT_LEFT | DT_VCENTER);
            DrawText(hdc, L"结束时间 ", -1, &endTime, DT_LEFT | DT_VCENTER);
            DrawText(hdc, L"计划内容 ", -1, &content, DT_LEFT | DT_VCENTER);


            DrawText(hdc, L"编号", -1, &number, DT_CENTER | DT_VCENTER);
            DrawText(hdc, L"年", -1, &firstVWord, DT_CENTER | DT_VCENTER);
            firstVWord.bottom += VGap;
            firstVWord.top += VGap;
            DrawText(hdc, L"月", -1, &firstVWord, DT_CENTER | DT_VCENTER);
            firstVWord.bottom += VGap;
            firstVWord.top += VGap;
            DrawText(hdc, L"日", -1, &firstVWord, DT_CENTER | DT_VCENTER);
            firstVWord.bottom += VGap;
            firstVWord.top += VGap;
            DrawText(hdc, L"时", -1, &firstVWord, DT_CENTER | DT_VCENTER);
            firstVWord.bottom += VGap;
            firstVWord.top += VGap;
            DrawText(hdc, L"分", -1, &firstVWord, DT_CENTER | DT_VCENTER);
            firstVWord.bottom = ADD_HEIGHT - 261;
            firstVWord.top = 120;

            EndPaint(hWnd, &ps);
            return 0;
        case WM_COMMAND:
            switch (LOWORD(wParam)) {
                case 0xf0:;
                    bool isVerified = true;
                    int tmp[10];
                    WCHAR buf[5];
                    WCHAR longBuf[TODO_LENGTH + 1];
                    int *ptr = &(data.start_date.year);
                    for (int i = 0; i < 10; ++i) {
                        int criterion = (i == 0 || i == 5) ? 4 : 2;
                        GetWindowText(editBoxes[i], buf, 5);
//                       Test code
//                       MessageBox(hWnd, buf, L"TEST", MB_OK);
                        if (GetWindowTextLength(editBoxes[i]) != criterion) {
                            goto input_error;
                        }
                        swscanf(buf, L"%d", ptr);
                        ptr += 1;
                    }

                    GetWindowText(editBoxes[11], buf, 5);
                    swscanf(buf, L"%d", &(data.number));

                    if (GetWindowTextLength(editBoxes[10]) >= TODO_LENGTH) goto input_error;
                    if (!isModify && verify_id(currentHead, data) == false) goto input_error;
                    if (verify_time(data.start_date, data.due_date) == false) goto date_error;

                    GetWindowText(editBoxes[10], longBuf, TODO_LENGTH + 1);
                    wcscpy(data.todo, longBuf);

                    while (0) {
                        input_error:
                        isVerified = false;
                        MessageBox(hWnd, L"数据格式错误", L"错误", MB_OK);
                    }
                    while (0) {
                        date_error:
                        isVerified = false;
                        MessageBox(hWnd, L"起止时间错误", L"错误", MB_OK);
                    }
                    if (isVerified) {
                        dataUsable = true;
                        DestroyWindow(hWnd);
                    }
                    break;
                case 0xf1:
                    DestroyWindow(hWnd);
// TODO: DELETE TEST DATA
//                    WCHAR str[TODO_LENGTH + 300];
//                    swprintf(str, TODO_LENGTH + 300, L"%d\n%d-%d-%d-%d:%d\n%d-%d-%d-%d:%d\nNOTE IS IN THE NEXT MESSAGEBOX",
//                             // number
//                             data.number,
//                             // two dates
//                             data.start_date.year, data.start_date.month, data.start_date.day,
//                             data.start_date.hour, data.start_date.minute,
//                             data.due_date.year, data.due_date.month, data.due_date.day,
//                             data.due_date.hour, data.due_date.minute);
//                    MessageBox(hWnd, str, L"TEST", MB_OK);
//                    MessageBox(hWnd, data.todo, L"NOTE", MB_OK);
                    break;
            }
            break;
//        case WM_CHAR:
//        case WM_KEYDOWN:
//            if (wParam == VK_TAB) {
//                SetFocus(editBoxes[currentPosition]);
//                currentPosition = (currentPosition + 1) % 12;
//            }
//            break;
        case WM_CLOSE:
            DestroyWindow(hWnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}


void open_add_window(HWND hWnd, bool is_modify, list_head head) {

    currentHead = head;
    isModify = is_modify;

    EnableWindow(hWnd, false);

    LPCWSTR lpWindowName = (isModify) ? L"修改数据" : L"添加数据";
    LPCWSTR lpClassName = L"mWndAddClass";

    HWND hAddWnd = CreateWindowEx(
            WS_EX_LEFT, lpClassName,
            lpWindowName,
            WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX,
            120,
            120,
            ADD_WIDTH + 16,
            ADD_HEIGHT + 39,
            hWnd,
            NULL,
            (HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
            NULL
    );


    // Display window
    ShowWindow(hAddWnd, SW_SHOW);
    UpdateWindow(hAddWnd);

    // Msg loop
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    EnableWindow(hWnd, true);
    SetForegroundWindow(hWnd);
    is_modify = false;
}


bool get_data(day_data *mDataPtr) {
    if (!dataUsable) {
        return false;
    } else {
        *mDataPtr = data;
        return true;
    }
}

bool put_data(day_data mData) {
    data = mData;
}